import {Component, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output, ViewChild} from '@angular/core';
import {catchError} from 'rxjs/operators';
import {NzMessageService} from 'ng-zorro-antd';
import {SysCommandService} from '../service/sys-command.service';
import {baseHandleError, BaseWebSocket, ReturnForm} from '@sb/base';
import {environment} from '../../../../../environments/environment';

@Component({
    selector: 'command-send',
    templateUrl: './command-send.component.html',
    styleUrls: ['./command-send.component.less']
})
export class CommandSendComponent implements OnInit, OnDestroy {

    webSocket: BaseWebSocket;

    @Input()
    commandId: string;

    @Input()
    command: string;

    commandInner: string;

    textarea: string;

    @ViewChild('textAreaElement', {static: true, read: ElementRef})
    textAreaElement: ElementRef;

    scroll = true;

    get scrollFrame() {
        return this.scroll;
    }

    set scrollFrame(_scroll) {
        this.scroll = _scroll;
        if (_scroll) {
            const element = this.textAreaElement.nativeElement;
            element.value += ' ';
            element.setSelectionRange(0, 0);
            element.scrollTop = element.scrollHeight;
        }
    }

    @Output()
    closeChange = new EventEmitter();

    /**
     * ws地址
     */
    readonly url = `${this.commandService.baseServerUrl || environment.baseServerUrl}ws/command`.replace('http', 'ws');

    constructor(private message: NzMessageService,
                private commandService: SysCommandService) {
    }

    ngOnInit() {
        this.commandInner = this.command;
        this.sendCommand();
    }

    sendCommand() {
        if (this.webSocket) {
            this.message.info('当前已存在执行指令');
            return;
        }

        let command;
        let commandId;
        if (this.command === this.commandInner) {
            commandId = this.commandId;
            command = null;
        } else {
            commandId = null;
            command = this.commandInner;
        }
        if (!command && !commandId) {
            return;
        }
        const wsc = new BaseWebSocket();
        const sub = wsc.connectSubject.subscribe(() => {
            wsc.sendMessage(JSON.stringify({
                type: 'init',
                data: {
                    commandId: commandId,
                    command: command
                }
            }));
            sub.unsubscribe();
        });
        const disSub = wsc.disconnectSubject.subscribe(() => {
            this.webSocket = null;
            disSub.unsubscribe();
        });
        wsc.connect(this.url);

        this.webSocket = wsc;

        const v = wsc.messageSubject.pipe(
            catchError(baseHandleError<ReturnForm<string>>('post'))
        ).subscribe((returnForm) => {

            let data = '';
            if (returnForm.success) {
                const message: {
                    type: 'log' | 'finish';
                    message: string
                } = returnForm.message;
                data = message.message;
            } else {
                data = returnForm.errorMessage;
            }


            if (this.textAreaElement) {
                const element = this.textAreaElement.nativeElement;
                const selectionStart = element.selectionStart;
                const selectionEnd = element.selectionEnd;
                element.value += (data + '\n');
                element.setSelectionRange(selectionStart, selectionEnd);
                if (selectionEnd > 0 || selectionStart > 0) {
                    this.scroll = false;
                }
                // 处理同步滚动
                if (this.scroll) {
                    element.scrollTop = element.scrollHeight;
                }
            } else {
                this.textarea += (data + '\n');
            }
        });
    }

    stopCommand() {
        this.webSocket.sendMessage(
            JSON.stringify({
                    type: 'stop',
                }
            )
        );
    }

    ngOnDestroy(): void {
        if (this.webSocket) {
            this.webSocket.close();
        }
    }

    closeClick() {
        this.closeChange.emit();
    }

    clearScreen() {
        this.textAreaElement.nativeElement.value = '';
    }


}
